package com.keyue.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.keyue.common.constant.Constant;
import com.keyue.common.constant.ServerResult;
import com.keyue.common.constant.ServerResultCode;
import com.keyue.common.exception.BusinessException;
import com.keyue.common.utils.AliOssUtil;
import com.keyue.common.utils.FileUtil;
import com.keyue.common.utils.MinIOUtil;
import com.keyue.common.utils.StringUtils;
import com.keyue.config.AliOssConfig;
import com.keyue.domain.dto.LocalStorageDO;
import com.keyue.domain.vo.FileRespVO;
import com.keyue.domain.vo.ImageRespVO;
import com.keyue.domain.vo.LocalStorageQueryVO;
import com.keyue.domain.vo.LocalStorageVO;
import com.keyue.mapper.LocalStorageMapper;
import com.keyue.service.LocalStorageService;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.List;
import java.util.Objects;

/**
 * 本地存储(LocalStorage)表服务实现类
 *
 * @author makejava
 * @since 2023-10-08 14:52:36
 */
@Slf4j
@Service
public class LocalStorageServiceImpl extends ServiceImpl<LocalStorageMapper, LocalStorageDO> implements LocalStorageService {


    @Value("${file.path}")
    private String path;

    @Value("${file.host}")
    private String host;

    @Value("${file.maxSize}")
    private long maxSize;

    @Override
    public ServerResult getUrl2ossV2(String name) {
        ImageRespVO imageRespVO = new ImageRespVO();
        return ServerResult.success(imageRespVO);
    }

    @Override
    public ServerResult uploadByAliOssV2(String name, MultipartFile file) {
        FileUtil.checkSize(maxSize, file.getSize());
        String fileName = AliOssUtil.getUniqueFileName(name);
        ImageRespVO imageRespVO = new ImageRespVO();
        try {
            AssumeRoleResponse response = AliOssUtil.buildAliyunSTSCredentials();
            if (AliOssUtil.uploadTemCertificate(response, AliOssConfig.ALIYUN_BUCKET, fileName, file.getBytes())) {
                String fileUrl = AliOssUtil.createAuthUrl(response, fileName, new DateTime().plusYears(Constant.ONE).toDate());
                imageRespVO.setPicUrl(fileUrl);
            }
            return ServerResult.success(imageRespVO);
        } catch (Exception e) {
            log.error("上传图片异常：{}", e.getMessage());
            throw new BusinessException(ServerResultCode.UPLOAD_IMAGES_ERROR);
        }
    }

    @Override
    public ServerResult uploadFileByAliOss(String name, MultipartFile file) {
        FileUtil.checkSize(maxSize, file.getSize());
        String fileName = AliOssUtil.getUniqueFileName(name);
        String tempFileName = "Thumbnails" + Constant.CROSS_BAR_CHARACTER + fileName;
        FileRespVO fileRespVO = new FileRespVO();
        try {
            File tempFile = new File(path + "files" + File.separator + tempFileName);
            if (AliOssUtil.upload(AliOssConfig.ALIYUN_BUCKET, fileName, file.getBytes())) {
                String fileUrl = AliOssUtil.createUrl(AliOssConfig.ALIYUN_BUCKET, fileName, new DateTime().plusYears(Constant.ENABLE_TEN).toDate());
                fileRespVO.setFileUrl(fileUrl);
                FileUtil.del(tempFile);
            }
            return ServerResult.success(fileRespVO);
        } catch (Exception e) {
            log.error("上传文件异常：{}", e.getMessage());
            throw new BusinessException(ServerResultCode.UPLOAD_IMAGES_ERROR);
        }
    }

    @Override
    public ServerResult uploadByAliOss(String name, MultipartFile file) {
        FileUtil.checkSize(maxSize, file.getSize());
        String fileName = AliOssUtil.getUniqueFileName(name);
        String tempFileName = "Thumbnails" + Constant.CROSS_BAR_CHARACTER + fileName;
        ImageRespVO imageRespVO = new ImageRespVO();
        try {
            File tempFile = new File(path + "images" + File.separator + tempFileName);
            if (AliOssUtil.upload(AliOssConfig.ALIYUN_BUCKET, fileName, file.getBytes())) {
                String originImageUrl = AliOssUtil.createUrl(AliOssConfig.ALIYUN_BUCKET, fileName, new DateTime().plusYears(Constant.ENABLE_TEN).toDate());
                imageRespVO.setPicUrl(originImageUrl);
                // 生成缩略图
                Thumbnails.of(file.getInputStream()).size(100, 100).toFile(tempFile);
                if (AliOssUtil.upload(AliOssConfig.ALIYUN_BUCKET, tempFileName, FileUtil.readBytes(tempFile))) {
                    String thumbnailImageUrl = AliOssUtil.createUrl(AliOssConfig.ALIYUN_BUCKET, tempFileName, new DateTime().plusYears(Constant.ENABLE_TEN).toDate());
                    imageRespVO.setSmallPicUrl(thumbnailImageUrl);
                }
                FileUtil.del(tempFile);
            }
            return ServerResult.success(imageRespVO);
        } catch (Exception e) {
            log.error("上传图片异常：{}", e.getMessage());
            throw new BusinessException(ServerResultCode.UPLOAD_IMAGES_ERROR);
        }
    }

    @Override
    public ServerResult uploadByMinIO(String name, MultipartFile file) {
        FileUtil.checkSize(maxSize, file.getSize());
        ImageRespVO imageRespVO = new ImageRespVO();
        try {
            imageRespVO.setPicUrl(MinIOUtil.uploadFile(file));
            return ServerResult.success(imageRespVO);
        } catch (Exception e) {
            log.error("上传图片异常：{}", e.getMessage());
            throw new BusinessException(ServerResultCode.UPLOAD_IMAGES_ERROR);
        }
    }

    @Override
    public ServerResult create(String name, MultipartFile multipartFile) {
        FileUtil.checkSize(maxSize, multipartFile.getSize());
        String suffix = FileUtil.getExtensionName(multipartFile.getOriginalFilename());
        String type = FileUtil.getFileType(suffix);
        File file = FileUtil.upload(multipartFile, path + type + File.separator);
        if (ObjectUtil.isNull(file)) {
            throw new BusinessException("上传失败");
        }
        try {
            name = StringUtils.isBlank(name) ? FileUtil.getFileNameNoEx(multipartFile.getOriginalFilename()) : name;
            LocalStorageDO localStorage = LocalStorageDO.builder()
                    .realName(file.getName())
                    .name(name)
                    .suffix(suffix)
                    .path(file.getPath())
                    .type(type)
                    .size(FileUtil.getSize(multipartFile.getSize())).build();
            save(localStorage);
            return ServerResult.success(host + "/images/" + file.getName());
        } catch (Exception e) {
            FileUtil.del(file);
            throw e;
        }
    }

    /**
     * 通过ID查询单条数据
     * <p>
     * localStorageQueryVO 主键
     *
     * @return 实例对象
     */
    @Override
    public ServerResult queryById(LocalStorageQueryVO localStorageQueryVO) {
        if (Objects.isNull(localStorageQueryVO.getId())) {
            return ServerResult.fail("id 不能为空");
        }
        LocalStorageDO LocalStorageDo = getById(localStorageQueryVO.getId());
        if (Objects.isNull(LocalStorageDo)) {
            return ServerResult.success(null);
        }
        return ServerResult.success(BeanUtil.copyProperties(LocalStorageDo, LocalStorageVO.class));
    }

    /**
     * 分页查询
     *
     * @param localStorageQueryVO 筛选条件
     * @return 查询结果
     */
    @Override
    public ServerResult list(LocalStorageQueryVO localStorageQueryVO) {

        return ServerResult.success();
    }

    /**
     * 新增数据
     *
     * @param localStorageVO 实例对象
     * @return 实例对象
     */
    @Override
    public ServerResult add(LocalStorageVO localStorageVO) {
        //todo 校验
        if (Objects.nonNull(localStorageVO.getId())) {
            localStorageVO.setId(null);
        }
        LocalStorageDO localStorageDo = BeanUtil.copyProperties(localStorageVO, LocalStorageDO.class);

        save(localStorageDo);

        return ServerResult.success();
    }

    /**
     * 修改数据
     *
     * @param localStorageVO 实例对象
     * @return 实例对象
     */
    @Override
    public ServerResult edit(LocalStorageVO localStorageVO) {
        //todo 校验
        if (Objects.isNull(localStorageVO.getId())) {
            return ServerResult.fail("id 不能为空");
        }
        LocalStorageDO localStorageDo = BeanUtil.copyProperties(localStorageVO, LocalStorageDO.class);

        updateById(localStorageDo);

        return ServerResult.success();
    }

    /**
     * 通过主键删除数据
     *
     * @param localStorageQueryVO 筛选条件
     * @return 是否成功
     */
    @Override
    public ServerResult deleteById(LocalStorageQueryVO localStorageQueryVO) {
        List<Long> ids = localStorageQueryVO.getIds();
        if (CollUtil.isEmpty(ids)) {
            return ServerResult.fail("ids 参数不能为空");
        }
        List<LocalStorageDO> localStorageList = listByIds(ids);
        if (CollUtil.isEmpty(localStorageList)) {
            return ServerResult.success();
        }
        //todo 校验是否可以逻辑删除
        LambdaUpdateWrapper<LocalStorageDO> updateWrapper = new LambdaUpdateWrapper<LocalStorageDO>()
                .in(LocalStorageDO::getId, ids)
                .set(LocalStorageDO::getEnableFlag, Constant.UNABLE_TWENTY);
        update(updateWrapper);
        return ServerResult.success();
    }
}
